package cn.org.donald.framework.service.impl;

import cn.org.donald.framework.service.SysPermissionService;
import cn.org.donald.framework.util.ListUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import cn.org.donald.framework.pojo.dto.AddRolePermissionDto;
import cn.org.donald.framework.pojo.dto.TagDto;
import cn.org.donald.framework.pojo.vo.ControllerPermissionVo;
import cn.org.donald.mapper.ControllerMapper;
import cn.org.donald.mapper.PermissionMapper;
import cn.org.donald.mapper.RolePermissionMapper;
import cn.org.donald.pojo.entity.system.Controller;
import cn.org.donald.pojo.entity.system.Permission;
import cn.org.donald.pojo.entity.system.Role;
import cn.org.donald.pojo.entity.system.RolePermission;
import org.apache.dubbo.config.annotation.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author ： Donald
 * @date ： 2020/10/18 01:41
 * @description：
 */
@Service(interfaceClass = SysPermissionService.class, version = "1.0.0",group = "donald")
public class SysPermissionServiceImpl implements SysPermissionService {

    private Logger logger = LoggerFactory.getLogger(SysPermissionServiceImpl.class);

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Autowired
    private ControllerMapper controllerMapper;


    @Override
    public List<Permission> findByRoleId(Long roleId) {
        QueryWrapper<RolePermission> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id",roleId);
        List<RolePermission> rolePermissions = rolePermissionMapper.selectList(queryWrapper);

        List<Permission> permissions = new ArrayList<>();
        rolePermissions.forEach(rolePermission -> {
            Permission permission1 = new Permission();
            permission1.setPermissionName(rolePermission.getPermissionName());
            QueryWrapper<Permission> permissionQueryWrapper = new QueryWrapper<>(permission1);
            Permission permission = permissionMapper.selectOne(permissionQueryWrapper);
            permissions.add(permission);
        });

        return permissions;
    }

    @Transactional
    @Override
    public int syncApi(List<Permission> pathList, List<TagDto> tagsList) {
        //先清表
        int deletePermission = permissionMapper.deletePhysical();
        int deleteController = controllerMapper.deletePhysical();
        int controllerRows = tagsList.stream()
                .mapToInt(
                        tag -> controllerMapper.insert(
                                new Controller(tag.getName(),tag.getDescription())
                        )
                ).sum();
        int permissionRows = pathList.stream()
                .mapToInt(
                        path -> permissionMapper.insert(path)
                ).sum();

        logger.info("删除permission表行数:{},删除controller表行数:{},插入permission表行数:{},插入controller表行数:{}",deletePermission,deleteController,permissionRows,controllerRows);
        return permissionRows;
    }

    @Override
    public List<ControllerPermissionVo> findTree(Long id) {
        /*获取全部controller*/
        List<Controller> controllerList = controllerMapper.selectList(null);
        QueryWrapper<Permission> permissionQueryWrapper = null;
        if (id != null){
            QueryWrapper<RolePermission> rolePermissionQueryWrapper = new QueryWrapper<>();
            rolePermissionQueryWrapper.eq("role_id",id);
            List<RolePermission> rolePermissions = rolePermissionMapper.selectList(rolePermissionQueryWrapper);
            List<String> strings = new ArrayList<>();
            rolePermissions.forEach(rolePermission -> strings.add(rolePermission.getPermissionName()));
            permissionQueryWrapper = new QueryWrapper<>();
            if (!strings.isEmpty()){
                permissionQueryWrapper.in("permission_name",strings);
            }else {
                permissionQueryWrapper.ne("1","1");
            }

        }
        List<Permission> permissions = permissionMapper.selectList(permissionQueryWrapper);
        Map<String, List<Permission>> collect =  permissions.stream().collect(Collectors.groupingBy(Permission::getControllerCode));
        List<ControllerPermissionVo> controllerPermissionVos = new ArrayList<>();
        controllerList.forEach(controller -> {
            ControllerPermissionVo controllerPermissionVo = new ControllerPermissionVo();
            BeanUtils.copyProperties(controller,controllerPermissionVo);
            controllerPermissionVo.setPermissionList(collect.get(controllerPermissionVo.getControllerCode()));
            controllerPermissionVos.add(controllerPermissionVo);
        });

        return controllerPermissionVos;
    }

    @Override
    public List<ControllerPermissionVo> findTreeByRoleId(Long id) {
        List<Permission> permissionList = findByRoleId(id);
        if (permissionList.isEmpty())return null;
        return getControllerPermissionVoByPermissionList(permissionList);
    }

    @Override
    public List<ControllerPermissionVo> findTreeNotByRoleId(Long id) {
        QueryWrapper<RolePermission> rolePermissionQueryWrapper = new QueryWrapper<>();
        rolePermissionQueryWrapper.eq("role_id",id);
        List<RolePermission> rolePermissions = rolePermissionMapper.selectList(rolePermissionQueryWrapper);
        List<Permission> permissionList = new ArrayList<>();
        rolePermissions.forEach(rolePermission -> {
            Permission permission = new Permission();
            permission.setPermissionName(rolePermission.getPermissionName());
            permissionList.add(permission);
        });
        List<Permission> permissions = findByPermissionNameNotIn(permissionList);

        if (permissions.isEmpty())return null;

        return getControllerPermissionVoByPermissionList(permissions);
    }


    @Override
    public List<Permission> findByPermissionNameNotIn(List<Permission> permissionList) {
        List<String> permissionNameList = new ArrayList<>();
        permissionList.forEach(permission -> permissionNameList.add(permission.getPermissionName()));
        QueryWrapper<Permission> queryWrapper = new QueryWrapper<>();
        queryWrapper.notIn("permission_name",permissionNameList);
        return permissionMapper.selectList(queryWrapper);
    }

    @Override
    public int insertRolePermissionBatch(AddRolePermissionDto addRolePermissionDto) {
        int rows = addRolePermissionDto.getPermissionList()
                .stream()
                .map(permission -> {
                    RolePermission rolePermission = new RolePermission();
                    rolePermission.setRoleId(addRolePermissionDto.getId());
                    rolePermission.setPermissionName(permission.getPermissionName());
                    return rolePermission;
                })
                .mapToInt(rolePermission -> rolePermissionMapper.insert(rolePermission))
                .sum();
        logger.info("添加权限记录 {} 行",rows);
        return rows;
    }

    @Override
    public List<RolePermission> findRolePermissionByRoleIds(List<Role> roleList) {
        List<Long> longs = new ArrayList<>();

        roleList.forEach(role -> longs.add(role.getId()));

        QueryWrapper<RolePermission> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("role_id",longs);
        return rolePermissionMapper.selectList(queryWrapper);
    }

    @Override
    public int deleteRolePermission(RolePermission rolePermission) {
        QueryWrapper<RolePermission> queryWrapper = new QueryWrapper<>(rolePermission);
        return rolePermissionMapper.delete(queryWrapper);
    }


    private List<ControllerPermissionVo> getControllerPermissionVoByPermissionList(List<Permission> permissionList){
        if (ListUtil.isEmptyOrHasClassFieldAllEmpty(permissionList)){
            return new ArrayList<>();
        }
        Map<String, List<Permission>> collect = permissionList.stream().collect(Collectors.groupingBy(Permission::getControllerCode));
        List<ControllerPermissionVo> controllerPermissionVoList = new ArrayList<>();
        collect.forEach((k,v) -> {
            ControllerPermissionVo controllerPermissionVo = new ControllerPermissionVo();
            QueryWrapper<Controller> controllerQueryWrapper = new QueryWrapper<>();
            controllerQueryWrapper.eq("controller_code",k);
            Controller controller = controllerMapper.selectOne(controllerQueryWrapper);
            BeanUtils.copyProperties(controller,controllerPermissionVo);
            controllerPermissionVo.setPermissionList(v);
            controllerPermissionVoList.add(controllerPermissionVo);
        });
        return controllerPermissionVoList;
    }
}
